The DXL reference manual states something like:
void passMeAFunction(string f(string)) {
}
string returnStringFuncString() (string){
}
string titleCaseStr(string str) {
string retVal = "";
int len = length(str);
if (len > 0) {
retVal = (upper("" str[0] "")) str[1:(len-1)];
}
return retVal;
}
string returnAStringProcessingFunction()(string) {
return titleCaseStr;
}
void functionFun() {
string str = "ABCD";
string string1 = lower(str);
print "string1 = " string1 "\n";
print "Titlecase aaa is " returnAStringProcessingFunction()("aaaa") "\n";
}
functionFun(); // call it
void ACTUAL_printThis(string p1) {
print("p1 = " p1 "\n");
}
void testAliases() {
//-------------------------------------
// This works (no suprise)
//-------------------------------------
ACTUAL_printThis("Parameter 1");
//---------------------------------------------------------------------------
// The below appears to conform to the syntax of an alias
// (e.g., <Type>& <AliasVarName> = <ActualItemToAlias>;
// It compiles but does not work
//---------------------------------------------------------------------------
// Left is (desired) "alias to void function that takes a string parameter"
void& printThis()(string) = ACTUAL_printThis; // compiles
// printThis("Parameter ONE"); // COMPILER: incorrect use of identifier (printThis)
}
testAliases(); // Call it
SystemAdmin - Thu Jun 24 15:57:03 EDT 2010 |
Re: Can DXL functions be aliased?
Ok first if you declare void ACTUAL_printThis(string) you cannot set void& printThis()(string) = ACTUAL_printThis. The declaration types don't match since ACTUAL_printThis returns void not string ... That is why you get the compile error.
int test(int a) {
print "Hello " a "\n"
return a + 1
}
int dereference( int func(int), int par ) {
return func(par)
}
print test 4
int x = (addr_ test)
print dereference (addr_ x, 4)
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Can DXL functions be aliased? Mathias Mamsch - Fri Jun 25 17:07:55 EDT 2010
Ok first if you declare void ACTUAL_printThis(string) you cannot set void& printThis()(string) = ACTUAL_printThis. The declaration types don't match since ACTUAL_printThis returns void not string ... That is why you get the compile error.
int test(int a) {
print "Hello " a "\n"
return a + 1
}
int dereference( int func(int), int par ) {
return func(par)
}
print test 4
int x = (addr_ test)
print dereference (addr_ x, 4)
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Thanks for the reply. (functionName())(P1, P2, ...); // ugly
::.(NewTypeName left, aliasedFunction) to do: instanceOfNewType.memberFunction(P1, P2, ...); // as an alternate to: memberFunction(instanceOfNewType, P1, P2, ...);
(instanceOfNewType.memberFunction())(P1, P2, ...);
|
Re: Can DXL functions be aliased? SystemAdmin - Fri Jun 25 18:40:35 EDT 2010
Thanks for the reply. (functionName())(P1, P2, ...); // ugly
::.(NewTypeName left, aliasedFunction) to do: instanceOfNewType.memberFunction(P1, P2, ...); // as an alternate to: memberFunction(instanceOfNewType, P1, P2, ...);
(instanceOfNewType.memberFunction())(P1, P2, ...);
You can have the objectInstance.memberFunction (parameter, ...) syntax, but you need to do it like the dxl developers did it (for example the properties of the HistoryRecord, etc. are accessed by x.y = z).
struct memberFuncType__ {}
memberFuncType__ memberFunction (int par1, string par2) {
// put all the parameters into a DXL object or something
DxlObject x = new()
x->"par1" = par1
x->"par2" = par2
return (addr_ x) memberFuncType__
}
struct Type {}
void ::.(Type var, memberFuncType__ var2) {
DxlObject parameters = (addr_ var2) DxlObject
int par1 = (parameters->"par1") int
string par2 = (parameters->"par2") string
// do the code ...
}
Type y
y.memberFunction (1, "Hallo")
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Can DXL functions be aliased? Mathias Mamsch - Mon Jun 28 11:09:51 EDT 2010
You can have the objectInstance.memberFunction (parameter, ...) syntax, but you need to do it like the dxl developers did it (for example the properties of the HistoryRecord, etc. are accessed by x.y = z).
struct memberFuncType__ {}
memberFuncType__ memberFunction (int par1, string par2) {
// put all the parameters into a DXL object or something
DxlObject x = new()
x->"par1" = par1
x->"par2" = par2
return (addr_ x) memberFuncType__
}
struct Type {}
void ::.(Type var, memberFuncType__ var2) {
DxlObject parameters = (addr_ var2) DxlObject
int par1 = (parameters->"par1") int
string par2 = (parameters->"par2") string
// do the code ...
}
Type y
y.memberFunction (1, "Hallo")
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
Thanks for your reply. What you've shown looks like it will work.
StringStackType stringStack = (null);
//--- Function Proxy ---
string upper(string str) {
string retVal = "undefined function";
// Retrieve the variant the use said to call
string whatToDo = StringStack_pop(stringStack);
print("In upper, whatToDo = " (whatToDo) "\n");
//--------------------------------------------------------------------------
// Here we could have N functions with the same signature.
// Based on the popped variation (pushed by the ::. function), we resolve
// which real function the user wanted to call.
//--------------------------------------------------------------------------
DxlObject dummyDxlObject = new();
if (whatToDo == "Super") {
retVal = Super_upper(Super_castAsSuper(dummyDxlObject), str);
} else if (whatToDo == "NumberTranslator") {
retVal = NumberTranslator_upper(NumberTranslator_castAsNumberTranslator(dummyDxlObject), str);
} else if (whatToDo == "NumberTranslator2") {
retVal = NumberTranslator2_upper(NumberTranslator2_castAsNumberTranslator2(dummyDxlObject), str);
}
delete dummyDxlObject;
return retVal;
}
//*** Maps ****************
_m ::.(Super p1, _m p2) {
// Push the variant to call later
StringStack_push(stringStack, "Super");
return p2
}
_m ::.(NumberTranslator p1, _m p2) {
// Push the variant to call later
StringStack_push(stringStack, "NumberTranslator");
return p2
}
_m ::.(NumberTranslator2 p1, _m p2) {
// Push the variant to call later
StringStack_push(stringStack, "NumberTranslator2");
return p2
}
void myTests() {
stringStack = StringStack_construct();
// Super is a collection of DXL functions that
// have a signature clash with user-type functions
// with the same signature
Super super = Super_construct();
NumberTranslator nt = NumberTranslator_construct();
NumberTranslator2 nt2 = NumberTranslator2_construct();
string result;
string myString = "aaa";
result = super.upper(nt2.upper(myString));
print("super.upper(nt2.upper(myString)) = " result "\n");
result = nt.upper(myString);
print("nt.upper(myString) = " result "\n");
result = nt2.upper(myString);
print("nt2.upper(myString) = " result "\n");
StringStack_destruct(stringStack);
}
myTests();
_m ::.(NumberTranslator p1, _m p2) {
// Push the variant to call later
StringStack_push(stringStack, "NumberTranslator");
return p2
|
Re: Can DXL functions be aliased? SystemAdmin - Mon Jun 28 16:05:12 EDT 2010
Thanks for your reply. What you've shown looks like it will work.
StringStackType stringStack = (null);
//--- Function Proxy ---
string upper(string str) {
string retVal = "undefined function";
// Retrieve the variant the use said to call
string whatToDo = StringStack_pop(stringStack);
print("In upper, whatToDo = " (whatToDo) "\n");
//--------------------------------------------------------------------------
// Here we could have N functions with the same signature.
// Based on the popped variation (pushed by the ::. function), we resolve
// which real function the user wanted to call.
//--------------------------------------------------------------------------
DxlObject dummyDxlObject = new();
if (whatToDo == "Super") {
retVal = Super_upper(Super_castAsSuper(dummyDxlObject), str);
} else if (whatToDo == "NumberTranslator") {
retVal = NumberTranslator_upper(NumberTranslator_castAsNumberTranslator(dummyDxlObject), str);
} else if (whatToDo == "NumberTranslator2") {
retVal = NumberTranslator2_upper(NumberTranslator2_castAsNumberTranslator2(dummyDxlObject), str);
}
delete dummyDxlObject;
return retVal;
}
//*** Maps ****************
_m ::.(Super p1, _m p2) {
// Push the variant to call later
StringStack_push(stringStack, "Super");
return p2
}
_m ::.(NumberTranslator p1, _m p2) {
// Push the variant to call later
StringStack_push(stringStack, "NumberTranslator");
return p2
}
_m ::.(NumberTranslator2 p1, _m p2) {
// Push the variant to call later
StringStack_push(stringStack, "NumberTranslator2");
return p2
}
void myTests() {
stringStack = StringStack_construct();
// Super is a collection of DXL functions that
// have a signature clash with user-type functions
// with the same signature
Super super = Super_construct();
NumberTranslator nt = NumberTranslator_construct();
NumberTranslator2 nt2 = NumberTranslator2_construct();
string result;
string myString = "aaa";
result = super.upper(nt2.upper(myString));
print("super.upper(nt2.upper(myString)) = " result "\n");
result = nt.upper(myString);
print("nt.upper(myString) = " result "\n");
result = nt2.upper(myString);
print("nt2.upper(myString) = " result "\n");
StringStack_destruct(stringStack);
}
myTests();
_m ::.(NumberTranslator p1, _m p2) {
// Push the variant to call later
StringStack_push(stringStack, "NumberTranslator");
return p2
Awesome find ... It is really hard to believe that this works, but it does.
struct MyType {}
void test(int a) {
print "in test " a "\n"
}
_m ::.(MyType x, _m p2) {
print "In operator\n"
return p2
}
MyType v = null
v.test 4
(CC: ( 1.i0( BlockI 0 3 0) 1.i4( IntAss, 1.i9, 1.i16, 1.i22) // translates to 'obj = currentObj() 1.i9( PushVarA, obj, 0, 0)^ 1.i14( Nop) 1.i15( Nop) 1.i16(CurrentObj)^ 1.i20( Nop) 1.i21( Nop) 1.i22( Pop) 1.i25( IntAss, 1.i30, 1.i37, 1.i43) 1.i30( PushVarA, attrDXLName, 0, 1)^ // translates to: attrDXLName = AttrDXLNameGet 1.i35( Nop) 1.i36( Nop) 1.i37(AttrDXLNameGet)^ 1.i41( Nop) 1.i42( Nop) 1.i43( Pop) 1.i46( Jump, 1.i136) // jmp to 136 --> 1.i50( BlockI 0 0 1) // start of function test 1.i54(StringPrint, 1.i58, 1.i89) 1.i58(StringConcat, 1.i63, 1.i70, ) 1.i63( Push da[4(in test )])^ 1.i68( Nop) 1.i69( Nop) 1.i70(StringIntConcat, 1.i75, 1.i82, ) 1.i75( PushVarC, a, 1, 0)^ 1.i80( Nop) 1.i81( Nop) 1.i82( Push da[13])^ 1.i87( Nop) 1.i88( Nop) 1.i89( ReUnAss #Q#(192)) 1.i93( BlockE 0 0 1) 1.i97( Ret) 1.i100( BlockI 1 0 1) // start of function ::. () 1.i104(StringPrint, 1.i108, 1.i115) 1.i108( Push da[20(In operator )])^ 1.i113( Nop) 1.i114( Nop) 1.i115( RetV) 1.i118( PushVarC, p2, 1, 1)^ 1.i123( Nop) 1.i124( Nop) 1.i125( ReUnAss #Q##(216)) 1.i129( BlockE 1 0 1) 1.i133( Ret) 1.i136( IntAss, 1.i141, 1.i148, 1.i154) // start of main program 1.i141( PushVarA, v, 0, 2)^ // translates to v = null 1.i146( Nop) 1.i147( Nop) 1.i148( NullPtr)^ 1.i152( Nop) 1.i153( Nop) 1.i154( Pop) 1.i157( CallFn, 1.i162, 1.i185, 1.i192) // This means execute 162, then execute 185, then execute the result of 162. 1.i162(CallFnRes, 1.i167, 1.i174, ) // Instead of pushing a function address here 'push xy', 1.i167( Push #Q##(216))^ // we have the function call to the . operator here! 1.i172( Nop) // Thats weird! 1.i173( Nop) 1.i174( PushVarC, v, 0, 2) 1.i178( Push #Q#(192))^ 1.i183( Nop) 1.i184( Nop) 1.i185( Push 4)^ 1.i190( Nop) 1.i191( Nop) 1.i192( Nop) 1.i195( ReUnAss #Q#(168)) 1.i199( ReUnAss #Q#(96)) 1.i203( BlockE 0 3 0)^ 1.i208( Nop) 1.i209( Nop) ) )
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|